package exam.axhu.service.impl;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import org.hibernate.Query;
import org.hibernate.SessionFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import exam.axhu.entity.Exam;
import exam.axhu.entity.ExamPaper;
import exam.axhu.entity.TestPaper;
import exam.axhu.service.ExamService;

@Service @Transactional
public class ExamServiceImpl implements ExamService{
//defaltBean: examServiceImpl
	@Resource SessionFactory factory;
	
//exam services
	
	public int addExam(Exam exam) {
		if(this.findByExamID(exam.getExamID())==null){
			factory.getCurrentSession().persist(exam);
			return 0;   //set up a new exam successfully
		}
		return 1;  //false, already has this exam
	}


	public void deleteExam(String... examIDs) {
		for(String examID : examIDs){
			if(this.findByExamID(examID)!=null)
			{
				this.deleteWholeExamPaper(examID);
				factory.getCurrentSession().delete(factory.getCurrentSession().load(Exam.class,examID)); 
			}
		}
	}

	public void updateExam(Exam exam) {
		factory.getCurrentSession().merge(exam);
		
	}

	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public Exam findByExamID(String examID){
		return (Exam) factory.getCurrentSession().get(Exam.class,examID);
	}
	
	
	@SuppressWarnings("unchecked")
	public List<Exam> findByCourseID(String courseID) {
		Query query = factory.getCurrentSession().createQuery("from Exam as c where c.courseID = :searchID");
		query.setString("searchID", courseID);
		if(query.list().size()!=0)
			return  query.list(); 
		else return null;
	}

	public int setStatus(Exam exam, int status){
		exam.setStatus(status);
		this.updateExam(exam);
		return status;
	}


// teacher services	
	
	public int addExamPaper(String examID, String item, String itemID) {
		if(this.searchExamPaper(examID, item, itemID)==null){
			factory.getCurrentSession().persist(new ExamPaper(examID, item, itemID));
			return 0;   //add a new item successfully
		}
		return 1;  //already has this record
	}

	public void deleteExamPaper(String examID, String item, String itemID){
		if(this.searchExamPaper(examID, item,itemID)!=null)
			factory.getCurrentSession().delete(factory.getCurrentSession().load(ExamPaper.class,this.searchExamPaper(examID, item,itemID).getExamPaperID()));			
	}
	
	public void deleteWholeExamPaper(String examID){
		List<ExamPaper> examPaperItems = this.listExamPaperByExamID(examID);
		if(examPaperItems!=null)
			for(ExamPaper item:examPaperItems)
			{
				factory.getCurrentSession().delete(factory.getCurrentSession().load(ExamPaper.class,item.getExamPaperID()));
				this.deleteWholeTestPaper(item.getExamPaperID());
			}
	}
	
	/*public void updateExamPaper(String examID, String item, String itemID){
		
		factory.getCurrentSession().merge(exam);
	}*/

	public void updateExamPaper(ExamPaper examPaper){
		factory.getCurrentSession().merge(examPaper);
	}

	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public ExamPaper searchExamPaper(String examID, String item, String itemID){
		Query query = factory.getCurrentSession().createQuery("from ExamPaper as c where c.examID = :searchExam and c.item = :searchItem and c.itemID = :searchItemID");
		query.setString("searchExam", examID);
		query.setString("searchItem", item);
		query.setString("searchItemID", itemID);
		if(query.list().size()!=0)
			return (ExamPaper) query.list().get(0); 
		else return null;
	}

	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public ExamPaper findByExamPaperID(String examPaperID){
		return (ExamPaper) factory.getCurrentSession().get(ExamPaper.class,examPaperID);
	}
	
	@SuppressWarnings("unchecked")
	public List<ExamPaper> listExamPaperByExamID(String examID) {
		Query query = factory.getCurrentSession().createQuery("from ExamPaper as c where c.examID = :searchExam");
		query.setString("searchExam", examID);
		if(query.list().size()!=0)
			return  query.list(); 
		else return null;
	}
	

	@SuppressWarnings("unchecked")
	public List<ExamPaper> listExamPaperByChoiceItem(String examID){
		Query query = factory.getCurrentSession().createQuery("from ExamPaper as c where c.examID = :searchExam and c.item = 'Choice'");
		query.setString("searchExam", examID);
		if(query.list().size()!=0)
			return  query.list(); 
		else return null;
	}
	
	@SuppressWarnings("unchecked")
	public List<ExamPaper> listExamPaperByJudgeItem(String examID){
		Query query = factory.getCurrentSession().createQuery("from ExamPaper as c where c.examID = :searchExam and c.item = 'Judge'");
		query.setString("searchExam", examID);
		if(query.list().size()!=0)
			return  query.list(); 
		else return null;
	}
	
	@SuppressWarnings("unchecked")
	public List<ExamPaper> listExamPaperByShortAnswerItem(String examID){
		Query query = factory.getCurrentSession().createQuery("from ExamPaper as c where c.examID = :searchExam and c.item = 'ShortAnswer'");
		query.setString("searchExam", examID);
		if(query.list().size()!=0)
			return  query.list(); 
		else return null;
	}
	
	// student services	
	
	public int addTestPaper(String examPaperID, String studentID, String answer) {
		if(this.searchTestPaper(examPaperID, studentID, answer)==null){
			factory.getCurrentSession().persist(new TestPaper(examPaperID, studentID, answer));
			return 0;   //add a new student successfully
		}
		return 1;  //already has this record
	}
	
	public int addTestPaper(String examPaperID, String studentID, String answer,int mark){
		if(this.searchTestPaper(examPaperID, studentID, answer)==null){
			factory.getCurrentSession().persist(new TestPaper(examPaperID, studentID, answer,mark));
			return 0;   //add a new student successfully
		}
		return 1;  //already has this record
	}

	public void deleteTestPaper(String examPaperID, String studentID, String answer){
		if(this.searchTestPaper(examPaperID, studentID, answer)!=null)
			factory.getCurrentSession().delete(factory.getCurrentSession().load(TestPaper.class,this.searchTestPaper(examPaperID, studentID, answer).getTestPaperID()));			
	}
	
	public  void deleteWholeTestPaper(String examPaperID){
		List<TestPaper> testPaperItems = this.listTestPaperByExamPaperID(examPaperID);
		if(testPaperItems!=null)
			for(TestPaper testPaperItem:testPaperItems)
				factory.getCurrentSession().delete(factory.getCurrentSession().load(TestPaper.class,testPaperItem.getTestPaperID()));
	}
	
	/*public void updateTestPaper(String examPaperID, String studentID, String answer){
		
	}*/
	
	public void updateTestPaper(TestPaper testPaper){
		factory.getCurrentSession().merge(testPaper);
	}

	public void updateTestPaper(int testPaperID, int mark){
		TestPaper newTestPaper = this.findByTestPaperID(testPaperID);
		newTestPaper.setMark(mark);
		this.updateTestPaper(newTestPaper);
	}
	
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public TestPaper findByTestPaperID(int testPaperID){
		return (TestPaper) factory.getCurrentSession().get(TestPaper.class,testPaperID);
	}
	
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public TestPaper searchTestPaper(String examPaperID, String studentID, String answer){
		Query query = factory.getCurrentSession().createQuery("from TestPaper as c where c.examPaperID = :searchExam and c.studentID = :searchStudent and c.answer = :searchAnswer");
		query.setString("searchExam", examPaperID);
		query.setString("searchStudent", studentID);
		query.setString("searchAnswer", answer);
		if(query.list().size()!=0)
			return (TestPaper) query.list().get(0); 
		else return null;
	}
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public TestPaper searchTest(String examPaperID, String studentID){
		Query query = factory.getCurrentSession().createQuery("from TestPaper as c where c.examPaperID = :searchExam and c.studentID = :searchStudent");
		query.setString("searchExam", examPaperID);
		query.setString("searchStudent", studentID);
		if(query.list().size()!=0)
			return (TestPaper) query.list().get(0); 
		else return null;
	}

	@SuppressWarnings("unchecked")
	public List<TestPaper> listTestPaperByExamPaperID(String examPaperID){
		Query query = factory.getCurrentSession().createQuery("from TestPaper as c where c.examPaperID = :searchExam");
		query.setString("searchExam", examPaperID);
		if(query.list().size()!=0)
			return  query.list(); 
		else return null;
	}
	
	@SuppressWarnings("unchecked")
	public List<TestPaper> listTestPaperByStudentID(String studentID){
		Query query = factory.getCurrentSession().createQuery("from TestPaper as c where c.studentID = :searchStudent");
		query.setString("searchStudent", studentID);
		if(query.list().size()!=0)
			return  query.list(); 
		else return null;
	}
	
	@SuppressWarnings("unchecked")
	public List<Exam> listExamsByCourseAndStatus(String courseID, int status){
		Query query = factory.getCurrentSession().createQuery("from Exam as c where c.courseID = :searchCourse and c.status = :searchStatus");
		query.setString("searchCourse", courseID);
		query.setLong("searchStatus", status);
		if(query.list().size()!=0)
			return  query.list(); 
		else return null;
	}
		
	
}
